<template>
  <input
    ref="fileInput"
    type="file"
    accept="images/*"
    multiple
    placeholder="选择你的文件"
    style="display: none"
    @change="inputSelection"
  />
  <button @click="openSelectionFile">上传文件</button>
  <div class="list" v-for="item in uploadFilesList" :key="item.label">
    <div class="label">{{ item.label }}</div>
    <div class="progress">{{ item.progress }}</div>
    <div class="pause" @click="pauseFileUpload(item)">暂停</div>
    <div class="reset" @click="resetFileUpload(item)" v-if="item.ongoing">
      重传
    </div>
    <div @click="removeFileUpload(item)">删除</div>
  </div>
</template>

<script setup lang="ts">
import { computed, ref } from "vue";
function generateUniqueId() {
  return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
    var r = crypto.getRandomValues(new Uint8Array(1))[0] % 16 | 0,
      v = c === "x" ? r : (r & 0x3) | 0x8;
    return v.toString(16);
  });
}
const uploadUrl = "http://localhost:3000/api/upload";
interface UploadFile {
  label: string;
  file: File;
  progress: number;
  formData: FormData;
  xhr: XMLHttpRequest;
  ongoing: boolean;
  uniqueId: string;
}
const uploadFilesList = computed(() => Object.values(uploadFilesObject.value));
const uploadFilesObject = ref<{
  [key: string]: UploadFile;
}>({});
const fileInput = ref<HTMLInputElement>();
function openSelectionFile() {
  fileInput.value?.click();
}
function inputSelection(event: Event) {
  const input = event.target as HTMLInputElement;
  const files = input?.files;

  for (const file of Object.values(files!)) {
    const uniqueId = generateUniqueId();
    uploadFilesObject.value[uniqueId] = {
      uniqueId,
      label: file.name,
      file,
      progress: 0,
      ongoing: true,
      formData: new FormData(),
      xhr: new XMLHttpRequest(),
    };
    uploadFile(uploadFilesObject.value[uniqueId]);
  }
  if (fileInput.value) {
    // 清空input的value
    fileInput.value.value = "";
  }
}

function uploadFile(uploadItem: UploadFile) {
  // 创建一个 FormData 对象，将文件添加到其中
  uploadItem.formData.append("file", uploadItem.file);

  // 设置请求的类型和 URL
  uploadItem.xhr.open("POST", uploadUrl, true);
  // 设置请求头
  uploadItem.xhr.setRequestHeader("Accept", "application/json");
  // xhr.setRequestHeader("Content-Type", "multipart/form-data");

  // 添加事件监听器，用于处理请求完成和失败的情况
  uploadItem.xhr.onload = () => {
    if (uploadItem.xhr.status === 200) {
      console.log("文件上传成功");
    } else {
      console.log("文件上传失败");
    }
  };
  uploadItem.xhr.onreadystatechange = function () {
    if (uploadItem.xhr.readyState === 3) {
      uploadItem.ongoing = true;
    } else {
      uploadItem.ongoing = false;
    }
  };
  uploadItem.xhr.onerror = () => {
    console.log("文件上传出错");
  };

  // 添加事件监听器，用于处理上传进度
  uploadItem.xhr.upload.onprogress = (event) => {
    if (event.lengthComputable) {
      // 计算上传进度百分比
      const progress = parseFloat(
        ((event.loaded / event.total) * 100).toFixed(2)
      );
      uploadItem.progress = progress;
      // 更新进度条的值
      console.log(`上传进度：${progress}%`);
    }
  };
  // 发送请求
  uploadItem.xhr.send(uploadItem.formData);
}

function pauseFileUpload(item: UploadFile) {
  if (item.xhr.readyState !== XMLHttpRequest.DONE) {
    item.xhr.abort();
  }
}

function resetFileUpload(item: UploadFile) {
  // 重新开始上传，类似于 resumeFileUpload
  item.xhr.open("POST", item.xhr.responseURL, true);
  item.xhr.send(item.formData);
}

function removeFileUpload(item: UploadFile) {
  if (item.xhr.readyState !== XMLHttpRequest.DONE) {
    item.xhr.abort();
  }

  delete uploadFilesObject.value[item.uniqueId];
}
</script>

<style lang="scss" scoped>
.list {
}
</style>
